<?php


namespace GordenSong\Support;


use GordenSong\Utils\RuleUtil;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable;

class Collection implements Arrayable
{
	use ValidatorTrait, PrefixTrait, Macroable;

	/**
	 * Collection constructor.
	 * @param Validator[]|\GordenSong\Support\Collection[]|array $validators
	 */
	public function __construct(array $validators)
	{
		foreach ($validators as $validator) {
			$this->add($validator);
		}
	}

	/**
	 * @param Validator|\GordenSong\Support\Collection $validator
	 * @return $this
	 */
	public function add($validator): Collection
	{
		if (!$validator instanceof Validator && !$validator instanceof Collection) {
			throw new \InvalidArgumentException();
		}

		$this->rules = RuleUtil::mergeManyRules($this->rules(), $validator->rules());
		$this->attributes = array_merge($this->attributes(), $validator->attributes());
		$this->messages = array_merge($this->messages(), $validator->messages());

		return $this;
	}

	/**
	 * @param \GordenSong\Support\Validator[]|\GordenSong\Support\Collection[]|array $validators
	 * @return Collection
	 */
	public static function make(array $validators = []): Collection
	{
		return new static($validators);
	}

	/**
	 * 只修改已有
	 * @param string|array|null $fields
	 * @return $this
	 */
	public function required(...$fields): Collection
	{
		if (func_num_args() == 0) {
			$fields = array_keys($this->rules);
		} else {
			$field = func_get_arg(0);
			$fields = is_array($field) ? $field : $fields;
		}
		foreach ($fields as $field) {
			$field = (string)$field;
			$rule = $this->getRule($field);
			if (is_string($rule)) {
				if ($rule && !Str::contains($rule, 'required')) {
					$this->rules[$field] .= '|required';
				}
			} elseif (is_array($rule)) {
				if (!in_array('required', $rule)) {
					$this->rules[$field][] = 'required';
				}
			}
		}
		return $this;
	}

	public function toArray(): array
	{
		return [
			'rules' => $this->rules(),
			'messages' => $this->messages(),
			'attributes' => $this->attributes(),
		];
	}
}
